package cc.shacocloud.mirage.restful.exception;

import cc.shacocloud.mirage.restful.bind.validation.BindingResult;
import cc.shacocloud.mirage.restful.bind.validation.errors.BindingResultError;
import cc.shacocloud.mirage.utils.MethodParameter;

/**
 * 当对注解为{@code @Valid}的参数进行验证失败时，将抛出异常。
 */
public class MethodArgumentNotValidException extends Exception {
    
    private final MethodParameter parameter;
    
    private final BindingResult bindingResult;
    
    /**
     * {@link MethodArgumentNotValidException}的构造函数。
     *
     * @param parameter     验证失败的参数
     * @param bindingResult 验证的结果
     */
    public MethodArgumentNotValidException(MethodParameter parameter, BindingResult bindingResult) {
        this.parameter = parameter;
        this.bindingResult = bindingResult;
    }
    
    /**
     * 返回验证失败的方法参数。
     */
    public MethodParameter getParameter() {
        return this.parameter;
    }
    
    /**
     * 返回失败验证的结果。
     */
    public BindingResult getBindingResult() {
        return this.bindingResult;
    }
    
    
    @Override
    public String getMessage() {
        StringBuilder sb = new StringBuilder("方法 '")
                .append(parameter.toString())
                .append("' 下标 [")
                .append(parameter.getParameterIndex()).append("] 参数类型 [")
                .append(parameter.getParameterType())
                .append("] 参数校验失败")
                .append(parameter.getExecutable().toGenericString());
        
        if (bindingResult.getErrorCount() > 1) {
            sb.append("，检查出").append(bindingResult.getErrorCount()).append("个错误");
        }
        
        sb.append(": ");
        for (BindingResultError error : bindingResult.getAllErrors()) {
            sb.append("[").append(error).append("] ");
        }
        return sb.toString();
    }
    
}
